package cn.tnar.parkservice.util;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by tieh on 2017/1/12.
 */
public class ParkingUtil {

    private static final Logger log = LoggerFactory.getLogger(ParkingUtil.class);

    public static final long MILLIS_PER_MIN = 60 * 1000;
    public static final long MINUTES_PER_DAY = 24 * 60;
    public static final int HOURS_PER_DAY = 24;
    public static final int MINUTES_PER_HOUR = 60;

    public static final DateTimeFormatter DATE_TIME = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    public static final DateTimeFormatter DATE = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    public static final DateTimeFormatter BASIC_DATE_TIME = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    public static final DateTimeFormatter BASIC_DATE = DateTimeFormatter.ofPattern("yyyyMMdd");
    public static final DateTimeFormatter BASIC_TIME = DateTimeFormatter.ofPattern("HHmmss");

    //字符转换
    public static int stringToFixedBytes(String str, byte by[]) {
        if (str == null) {
            return 0;
        }

        byte byTemp[] = str.getBytes();
        int strLen = byTemp.length;
        int byLen = by.length;

        if (strLen > byLen)
            return -1;

        if (strLen == 0)
            for (int i = 0; i < byLen; i++)
                by[i] = '\0';

        System.arraycopy(byTemp, 0, by, 0, strLen);
        return strLen;
    }


    /**
     * 转为BP格式的时间 如2017-1-12 10:56:59，则转为长整形 20170112105659L
     *
     * @return
     */
    public static long toBpTime(LocalDateTime time) {
        return Long.parseLong(BASIC_DATE_TIME.format(time));
    }

    public static String format(LocalDateTime time) {
        if (time == null) {
            return "";
        }
        return DATE_TIME.format(time);
    }
    public static String formatDate(LocalDateTime time) {
        if (time == null) {
            return "";
        }
        return DATE.format(time);
    }

    public static String formatBasic(LocalDateTime time) {
        if (time == null) {
            return "";
        }
        return BASIC_DATE_TIME.format(time);
    }
    public static String formatBasicDate(LocalDateTime time) {
        if (time == null) {
            return "";
        }
        return BASIC_DATE.format(time);
    }

    public static String formatBasicTime(LocalDateTime time) {
        if (time == null) {
            return "";
        }
        return BASIC_TIME.format(time);
    }

    public static String now() {
        return format(LocalDateTime.now());
    }
    public static String nowDate() {
        return formatDate(LocalDateTime.now());
    }

    public static String nowBasic() {
        return formatBasic(LocalDateTime.now());
    }
    public static String nowBasicDate() {
        return formatBasicDate(LocalDateTime.now());
    }
    public static String nowBasicTime() {
        return formatBasicTime(LocalDateTime.now());
    }

    /**
     * 'yyyyMMddHHmmss' String to 'yyyy-MM-dd HH:mm:ss' String
     *
     * @param time
     * @return
     */
    public static String fromLbm(String time) {
        try {
            return format(parseLbm(time));
        } catch (Exception e) {
            return "";
        }
    }

    private static LocalDateTime parseLbm(String time) {
        return LocalDateTime.from(BASIC_DATE_TIME.parse(time));
    }


    /**
     * 车辆类型
     * 0	小型车(蓝)
     * 1	中型车
     * 2	大型车(黄)
     * 3	军警车(白)
     * 4	时租车
     * 5	新能源(绿)
     */
    public static int mapColortoType(String color) {
        switch (color) {
            case "蓝":
                return 0;
            case "黄":
                return 2;
            case "白":
                return 3;
            case "绿":
                return 5;
            default:
                return 0;
        }
    }

    /**
     * 车辆会员类型
     * 0	临时车
     * 1	免费车
     * 2	储值卡
     * 3	月卡车
     * 4	时租车
     * 5	特征车
     */
    public static String getCarMemberString(int type) {
        switch (type) {
            case 0:
                return "临时车";
            case 1:
                return "免费车";
            case 2:
                return "储值卡";
            case 3:
                return "月卡车";
            case 4:
                return "时租车";
            case 5:
                return "特征车";
            default:
                return "临时车";
        }
    }

    /**
     * 计算时间间隔，并转为字符串"xx天xx小时xx分钟"
     *
     * @param start
     * @param end
     * @return
     */
    public static String between(Date start, Date end) {
        long min = Math.abs(end.getTime() - start.getTime()) / MILLIS_PER_MIN;
        long days = min / MINUTES_PER_DAY;
        long hours = min % MINUTES_PER_DAY / MINUTES_PER_HOUR;
        long mins = min % MINUTES_PER_HOUR;

        StringBuilder sb = new StringBuilder();
        if (days > 0) {
            sb.append(days).append("天");
        }
        if (hours > 0) {
            sb.append(hours).append("小时");
        }
        sb.append(mins).append("分");
        return sb.toString();
    }


    /**
     * xx分钟 ==> xx天xx小时xx分钟
     *
     * @return
     */
    public static String duration(String totalMin) {
        if (totalMin == null || totalMin.length() <= 0) {
            return "";
        }
        try {
            long nTotalMin = Long.parseLong(totalMin);
            long days = nTotalMin / MINUTES_PER_DAY;
            long hours = nTotalMin % MINUTES_PER_DAY / MINUTES_PER_HOUR;
            long mins = nTotalMin % MINUTES_PER_HOUR;

            StringBuilder sb = new StringBuilder();
            if (days > 0) {
                sb.append(days).append("天");
            }
            if (hours > 0) {
                sb.append(hours).append("小时");
            }
            sb.append(mins).append("分钟");
            return sb.toString();
        } catch (NumberFormatException e) {
            return "";
        }
    }

    /**
     * 计算时间间隔，并转为字符串"xx天xx小时xx分钟"
     *
     * @param start
     * @param end
     * @return
     */
    public static String between(LocalDateTime start, LocalDateTime end) {
        if (start == null || end == null) {
            return "";
        }
        Duration duration = Duration.between(start, end);
        long days = duration.toDays();
        long hours = duration.toHours() % HOURS_PER_DAY;
        long mins = duration.toMinutes() % MINUTES_PER_HOUR;

        StringBuilder sb = new StringBuilder();
        if (days > 0) {
            sb.append(days).append("天");
        }
        if (hours > 0) {
            sb.append(hours).append("小时");
        }
        sb.append(mins).append("分");
        return sb.toString();
    }


    public static final BigDecimal CENTS_PER_YUAN = new BigDecimal(100);

    public static BigDecimal toCent(BigDecimal yuan) {
        return yuan.multiply(CENTS_PER_YUAN);
    }

    public static BigDecimal toYuan(BigDecimal cent) {
        return cent.divide(CENTS_PER_YUAN, 2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * Double Cent to BigDecimal Yuan
     *
     * @param cent
     * @return
     */
    public static BigDecimal toYuan(double cent) {
        return toYuan(new BigDecimal(cent));
    }

    public static BigDecimal fromDouble(double amt) {
        return new BigDecimal(amt).setScale(2, BigDecimal.ROUND_HALF_UP);
    }


    /**
     * 支持Null的BigDecimal加法
     *
     * @param a
     * @param b
     * @return
     */
    public static BigDecimal add(BigDecimal a, BigDecimal b) {
        return orZero(a).add(orZero(b));
    }


    /**
     * 支持Null的BigDecimal减法
     *
     * @param a
     * @param b
     * @return
     */
    public static BigDecimal subtract(BigDecimal a, BigDecimal b) {
        return a.subtract(orZero(b));
    }


    /**
     * 支持Null的BigDecimal比较
     *
     * @param a
     * @param b
     * @return true if a > b
     */
    public static boolean larger(BigDecimal a, BigDecimal b) {
        return a.compareTo(orZero(b)) > 0;
    }

    /**
     * 返回0如果是Null
     *
     * @param b
     * @return 0 if b is Null
     */
    public static BigDecimal orZero(BigDecimal b) {
        return (b == null) ? new BigDecimal(0) : b;
    }

    /**
     * 计算间隔天数，不足一天算一天
     *
     * @param stime
     * @param etime
     * @return
     */
    public static long daysOf(String stime, String etime) {
        LocalDateTime start = parseLbm(stime);
        LocalDateTime end = parseLbm(etime);
        Duration duration = Duration.between(start, end);
        return duration.toDays() + 1;
    }

    public static String replace(String template, Map<String, String> map) {
        String result = template;
        System.out.println("长度："+map.size());
        for (Map.Entry<String, String> e : map.entrySet()) {
            System.out.println(e.getKey()+"-->>"+e.getValue());
            result = result.replace(e.getKey(), e.getValue());
        }
        return result;
    }
    public static String date(String date) throws ParseException {

        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        Date zDate=formatter.parse(date);
        formatter.applyPattern("yyyy年M月d日");
        String dd =formatter.format(zDate);
        return dd;
    }

    public static String getTime() {
        Calendar Cld = Calendar.getInstance();
        DateTimeFormatter DATE_TIME = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String time = DATE_TIME.format(LocalDateTime.now());
        //int MI = Cld.get(Calendar.MILLISECOND);
        return time;
    }

    public static String getTime(String format) {
        if (StringUtils.isBlank(format)){
            format = "yyyyMMddHHmmss";
        }
        DateTimeFormatter datetime = DateTimeFormatter.ofPattern(format);
        String time = datetime.format(LocalDateTime.now());
        return time;
    }

    public static String formatDateString(String date, String fromFormat, String toFormat) {
        if (fromFormat == null || fromFormat.length() == 0){
            fromFormat = "yyyyMMddHHmmss";
        }
        if (toFormat == null || toFormat.length() == 0){
            toFormat = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(fromFormat);
        SimpleDateFormat df = new SimpleDateFormat(toFormat);
        try {
            Date datenormal = sdf.parse(date);
            return df.format(datenormal);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "0";
    }

    //元转分
    public static int toFen(String amt){
        if (amt != null && amt.length() > 0){
            String fen = String.format("%.0f", Float.parseFloat(amt)*100);
            return Integer.parseInt(fen);
        }else {
            return 0;
        }
    }
    public static String toYuan(int fen){
        if (fen > 0){
            return String.format("%.02f", fen/100.0);
        }else{
            return "0";
        }
    }
    public static String dateToUnix(String date, String fromFormat) {
        if (fromFormat == null || fromFormat.length() == 0){
            fromFormat = "yyyyMMddHHmmss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(fromFormat);
        try {
            Date datenormal = sdf.parse(date);
            return datenormal.getTime()/1000+"";
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "0";
    }

    public static String unixTime() {
        return System.currentTimeMillis()/1000L+"";
    }

    //是否为空或0
    public static boolean isNullEmpty(String string){
        if (StringUtils.isBlank(string) || string == null || string.length() == 0 || "0".equals(string)
                || string.indexOf("null") >= 0){
            return true;
        }
        return false;
    }
    public static boolean isNotNullEmpty(String string){
        return !isNullEmpty(string);
    }
    public static boolean isNumber(String string){
        if (string == null || string.length() == 0){
            return false;
        }
        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher isNum = pattern.matcher(string);
        if(!isNum.matches()){
            return false;
        }
        return true;
    }
    public static String currentPlusMinutes(Long minute){
        if (minute > 0){
            return ParkingUtil.formatBasic(LocalDateTime.now().plusMinutes(minute));
        }else{
            return ParkingUtil.formatBasic(LocalDateTime.now().plusMinutes(60));
        }
    }
    public static String generateNonceStr() {
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
    }
    public static String generateNonceStr(int length) {
        if (length <= 0){
            length = 32;
        }
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, length);
    }
    public static int buildRandom(int length) {
        int num = 1;
        double random = Math.random();
        if (random < 0.1) {
            random = random + 0.1;
        }
        for (int i = 0; i < length; i++) {
            num = num * 10;
        }
        return (int) ((random * num));
    }

    public static String getTimeBySecond(int second,String fmt){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, second);
        return new SimpleDateFormat(fmt).format(calendar.getTime());
    }
    public static String getTimeByDay(int day,String fmt){
        Calendar calendar = Calendar.getInstance();
        int dayTime = calendar.get(Calendar.DATE);
        calendar.set(Calendar.DATE, dayTime+day);
        return new SimpleDateFormat(fmt).format(calendar.getTime());
    }
    public static String getTimeByMonth(int month,String fmt){
        Calendar calendar = Calendar.getInstance();
        int monthTime = calendar.get(Calendar.MONTH);
        calendar.set(Calendar.MONTH, monthTime+month);
        return new SimpleDateFormat(fmt).format(calendar.getTime());
    }

    public static String cmbParkCodeParse(String park_code){
        if (ParkingUtil.isNotNullEmpty(park_code)){
            try {
                String path = System.getProperty("user.dir")+"/epay/cmb_parks.json";
                File myFile = new File(path);
                if (myFile.exists()){
                    log.info("cmb json file exist path:"+path);
                    String input = FileUtils.readFileToString(myFile, "UTF-8");
                    JsonParser parse = new JsonParser();
                    JsonObject obj = (JsonObject) parse.parse(input);
                    if (obj.has(park_code)){
                        //
                        return obj.get(park_code).getAsString();
                    }
                }else{
                    log.info("cmb json file not exist path:"+path);
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        //默认停哪儿停车场
        return "4201150001";
    }
}
